#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "proc.h"

#define FALSE 0
#define TRUE 1

int assert_equals(int arg1, int arg2)
{
	return (arg1 == arg2);
}
int assert_string_equals(char *arg1, char *arg2)
{
	return !strcmp(arg1, arg2);
}

struct proc new_proc(char *name, int pid, int ppid)
{
	struct proc temp_proc;
	memcpy(temp_proc.name, name , strlen(name));
	temp_proc.pid = pid;
	temp_proc.ppid = ppid;
	temp_proc.parent = temp_proc.child = temp_proc.sibling = -1;
	temp_proc.level = 0;

	return temp_proc;
}

/* Must be init and pid ==1
 */
int test_root()
{
	struct proc temp = proc_tree[find_root()];

	if(!assert_equals(temp.pid, 1)) // check pid must be 1
		return !printf ("FAILED: %s line %d\n", __func__, __LINE__-1);
	if(!assert_equals(temp.ppid, 0)) // check ppid Must be 0
		return !printf ("FAILED: %s line %d\n", __func__, __LINE__-1);
	if(!assert_equals(temp.level, 0)) // level must be 0
		return !printf ("FAILED: %s line %d\n", __func__, __LINE__-1);

	return TRUE;
}

/*
 * check that the first child gets added
 */
int test_child1()
{
	struct proc child1 = proc_tree[proc_tree[find_root()].child];
	if (!assert_equals(child1.parent, find_root())) // parent must be root
		return !printf ("FAILED: %s line %d\n", __func__, __LINE__-1);
	if(!assert_equals(child1.level, 1)) // Level must be 1
		printf ("FAILED: %s line %d\n", __func__, __LINE__-1);

	return TRUE;
}

/*
 * check sibling
 */
int test_sibling()
{
	int first_child = proc_tree[find_root()].child;
	int last_child = proc_tree[first_child].sibling;
	while (proc_tree[last_child].sibling != -1)
		last_child = proc_tree[last_child].sibling;

	if (!assert_equals(proc_tree[last_child].parent, find_root())) // parent must be root
		return !printf ("FAILED: %s line %d\n", __func__, __LINE__-1);
	if(!assert_equals(proc_tree[last_child].level, 1)) // Level must be 1
		printf ("FAILED: %s line %d\n", __func__, __LINE__-1);

	return TRUE;
}

int main(int argc, char* argv[])
{
	printf ("=== proctree unit test begin ===\n\n");
	build_index();
	build_tree();
	mark_level();

	int passed = 0;
	int failed = 0;

	test_root() ? passed++ : failed++;
	test_child1() ? passed++ : failed++;
	test_sibling() ? passed++ : failed++;
	
	printf ("\n%d test(s) passed\n", passed);
	printf ("%d test(s) failed\n", failed);
	printf ("\n=== proctree unit test end ===\n");

	return 0;
}
